package cn.fintecher.pangolin.service.manage.web;

import cn.fintecher.pangolin.common.enums.OtherTemplateType;
import cn.fintecher.pangolin.common.model.UserModel;
import cn.fintecher.pangolin.entity.elastic.Template;
import cn.fintecher.pangolin.service.manage.elastic.TemplateElastic;
import cn.fintecher.pangolin.service.manage.request.CreateTemplateRequest;
import cn.fintecher.pangolin.service.manage.request.ModifyTemplateRequest;
import cn.fintecher.pangolin.service.manage.request.TemplateSearchRequest;
import cn.fintecher.pangolin.service.manage.response.LetterTemplateResponse;
import cn.fintecher.pangolin.service.manage.response.TemplateResponse;
import cn.fintecher.pangolin.service.manage.service.BaseService;
import cn.fintecher.pangolin.service.manage.service.TemplateService;
import com.google.common.collect.Lists;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.collections4.IterableUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.modelmapper.ModelMapper;
import org.modelmapper.TypeToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;

@RestController
@RequestMapping("/api/template")
@Api(value = "模板配置", description = "模板配置")
public class TemplateController {

    Logger log = LoggerFactory.getLogger(TemplateController.class);

    @Autowired
    TemplateElastic templateElastic;

    @Autowired
    ModelMapper modelMapper;

    @Autowired
    private TemplateService templateService;

    @Autowired
    private BaseService baseService;

    @GetMapping("/getAllTemplates")
    @ApiOperation(notes = "模板查询", value = "模板查询")
    public ResponseEntity<Page<TemplateResponse>> getAllTempletes(TemplateSearchRequest request,
                                                                  Pageable pageable, @RequestHeader(value = "X-UserToken") String token) {
        log.info("REST request to get All Templetes,{}", request);
        UserModel userModel = baseService.getUserByToken(token);
        BoolQueryBuilder builder = request.generateQueryBuilder();
        baseService.spliceBuilder(builder, userModel);
        SortBuilder sortBuilder = SortBuilders.fieldSort("operateTime").unmappedType("date").order(SortOrder.DESC);
        SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).withPageable(pageable).withSort(sortBuilder).build();
        Page<Template> page = templateElastic.search(searchQuery);
        Page<TemplateResponse> response = modelMapper.map(page, new TypeToken<Page<TemplateResponse>>() {
        }.getType());
        return ResponseEntity.ok().body(response);
    }

    @GetMapping("/getTemplateByType")
    @ApiOperation(notes = "根据模板类别查询模板", value = "根据模板类别查询模板")
    public ResponseEntity<List<LetterTemplateResponse>> getTemplateByType(OtherTemplateType templateType) {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.termsQuery("type.keyword", templateType.name()));
        List<Template> templateList = Lists.newArrayList(templateElastic.search(boolQueryBuilder));
        return ResponseEntity.ok().body(modelMapper.map(templateList, new TypeToken<List<LetterTemplateResponse>>() {
        }.getType()));
    }

    @PostMapping("/createTemplate")
    @ApiOperation(notes = "新增模板", value = "新增模板")
    public ResponseEntity<Void> createTemplete(@Valid @RequestBody CreateTemplateRequest request, @RequestHeader(value = "X-UserToken") String token) {
        log.info("REST request to create Templete,{}", request);
        templateService.createTemplete(request, token);
        return ResponseEntity.ok().body(null);
    }

    @PostMapping("/modifyTemplate")
    @ApiOperation(notes = "修改模板", value = "修改模板")
    public ResponseEntity<Void> modifyTemplete(@Valid @RequestBody ModifyTemplateRequest request,
                                               @RequestHeader(value = "X-UserToken") String token) {
        log.info("REST request to modify Templete,{}", request);
        templateService.modifyTemplete(request, token);
        return ResponseEntity.ok().body(null);
    }

    @DeleteMapping("/deleteTemplate")
    @ApiOperation(notes = "删除模板", value = "删除模板")
    public ResponseEntity<Void> deleteTemplete(@RequestParam String id) {
        log.info("REST request to delete Templete,{}", id);
        templateElastic.deleteById(id);
        return ResponseEntity.ok().build();
    }

    /**
     * 获取不同委托方下模板
     */
    @ApiOperation(value = "获取不同委托方下模板", notes = "获取不同委托方下模板")
    @GetMapping("/getTemplate")
    public ResponseEntity<List<Template>> getTemplate(@RequestParam @ApiParam(value = "模板类型", required = true) OtherTemplateType type,
                                                      @RequestParam @ApiParam(value = "委托方ID", required = true) String principalId) {
        log.info("REST request to get template,{},{}", type, principalId);
        BoolQueryBuilder builder = new BoolQueryBuilder();
        builder.must(QueryBuilders.matchPhraseQuery("type.keyword", type.name()));
        builder.must(QueryBuilders.matchPhraseQuery("principalId.keyword", principalId));
        builder.must(QueryBuilders.matchPhraseQuery("isEnabled.keyword", "YES"));
        List<Template> list = IterableUtils.toList(templateElastic.search(builder));
        return ResponseEntity.ok().body(list);
    }
}
